home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / utils / sort.arc / sortmain.c < prev    next >
C/C++ Source or Header  |  1989-03-30  |  15KB  |  368 lines

  1. /******************************************************************************
  2.  *                                                                            *
  3.  *   sortmain.c  version 1.0 of 22 Januari 1989    (C) L.J.M. de Wit 1989     *
  4.  *                                                                            *
  5.  * This software may be used and distributed freely if not used commercially  *
  6.  * and the originator (me) is mentioned in the source (just leave this 9 line *
  7.  * header intact).                                                            *
  8.  *                                                                            *
  9.  ******************************************************************************
  10.  *
  11.  * sortmain.c: main module for sort
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <ctype.h>
  16. #include "sortmain.h"
  17. #include "sortcomp.h"
  18. #include "sortfile.h"
  19.  
  20. typedef struct key {                            /* Sort key structure       */
  21.     int (*cmp)();                               /* Comparision routine      */
  22.     int bfld;                                   /* Begin field no.          */
  23.     int bchar;                                  /* Begin char no.           */
  24.     int echar;                                  /* End char no.             */
  25.     int flds;                                   /* # of fields (efld-bfld)  */
  26.     int bis0;                                   /* bfld == bchar == 0       */
  27.     int eis0;                                   /* efld == echar == 0       */
  28.     struct key *next;                           /* Next sort key ptr.       */
  29. } key;
  30.  
  31. int options = 0;                                /* Global sort type flag    */
  32. long _mneed = 40000;                            /* Memory occupied by prog  */
  33.  
  34. static char sepchar = ' ';                      /* Field separator char     */
  35. static key firstkey;                            /* First key used           */
  36.  
  37. static int compar();                            /* Standard compare routine */
  38. static int compb0(), compe0(), compbe();        /* Special cases of compar()*/
  39. static int bdfinr();                            /* Get 'bdfinr' options     */
  40. static char *(*fieldfunc)();
  41. static char *getsepfld(), *getspafld();         /* Search field + offset    */
  42. static int (*getcmp())();
  43. extern void allsort();
  44.  
  45. main(argc,argv)
  46. int argc;
  47. char **argv;
  48. {
  49.     int i, qualif;
  50.     char *s;
  51.     char *outfile = (char *)0;                  /* Result file (stdout)     */
  52.     key *keyp, *keyn;
  53.     int (*compfunc)();                          /* Routine used to compare  */
  54.     int nkeys = 0;                              /* No. of keys to be used   */
  55.  
  56.     settemp("\\tmp");                           /* Set default temp dir     */
  57.  
  58.     initlookup();                               /* Initialize lookup arrays */
  59.  
  60.     for (i = 1; i < argc && (*argv[i] == '-' ||
  61.                        *argv[i] == '+'); i++) { /* Handle commandline flags */
  62.         s = argv[i];
  63.         if (*s++ == '-') {
  64.             if (*s == '\0') {                   /* '-' denotes std input    */
  65.                 break;
  66.             }
  67.             for ( ; *s != '\0'; ) {
  68.                 if (qualif = bdfinr(*s)) {      /* *s in (b,d,f,i,n,r)      */
  69.                     options |= qualif;          /* Add it to options        */
  70.                     s++;
  71.                 } else {
  72.                     switch (*s++) {
  73.                     case 't':                   /* Field separator char     */
  74.                         sepchar = *s++;
  75.                         break;
  76.                     case 'c':                   /* Don't sort, only check   */
  77.                         options |= CHECKONLY;
  78.                         break;
  79.                     case 'm':                   /* Merge the sorted input   */
  80.                         options |= MERGEONLY;
  81.                         break;
  82.                     case 'o':                   /* Output file              */
  83.                         options |= OUTFILE;
  84.                         s += strlen(s);
  85.                         outfile = argv[++i];
  86.                         break;
  87.                     case 'T':                   /* Directory for temp files */
  88.                         options |= SEPARATOR;
  89.                         s += strlen(s);
  90.                         settemp(argv[++i]);
  91.                         break;
  92.                     case 'u':                   /* Remove duplicate lines   */
  93.                         options |= UNIQUE;
  94.                         break;
  95.                     default:                    /* Invalid option           */
  96.                         *s = '\0';              /* Null terminate           */
  97.                         error("invalid option %s\n",--s);
  98.                         break;
  99.                     }
  100.                 }
  101.             }
  102.         } else {                                /* '+' sort key flag        */
  103.             int keyflags = 0, efld = 0;
  104.  
  105.             if (nkeys++ == 0) {
  106.                 keyp = &firstkey;
  107.             } else {
  108.                 keyp = (key *)malloc(sizeof(key));/* Create the (next) key  */
  109.                 if (keyp == (key *)0) {
  110.                     error("memory allocation failed\n",(char *)0);
  111.                 }
  112.                 for (keyn = &firstkey; keyn->next != (key *)0;
  113.                                                          keyn = keyn->next) ;
  114.                 keyn->next = keyp;
  115.             }
  116.             keyp->next = (key *)0;
  117.             keyp->bfld = atoi(s);               /* Get key's start field no.*/
  118.             for ( ; isdigit(*s); s++) ;
  119.             if (*s == '.') {
  120.                 keyp->bchar = atoi(++s);        /* Get char offset for field*/
  121.                 for ( ; isdigit(*s); s++) ;
  122.             } else {
  123.                 keyp->bchar = 0;                /* 0 is default             */
  124.             }
  125.             for ( ; *s != '\0'; s++) {          /* 'bdfinr' flags for key   */
  126.                 if (qualif = bdfinr(*s)) {
  127.                     keyflags |= qualif;         /* Add flag                 */
  128.                 } else {
  129.                     s[1] = '\0';
  130.                     error("invalid option %s\n",s);
  131.                 }
  132.             }
  133.             if (i + 1 < argc && argv[i+1][0] == '-'  /* End field specified */
  134.                 && (argv[i+1][1] == '.' || isdigit(argv[i+1][1]))) {
  135.                 s = argv[++i] + 1;
  136.                 efld = atoi(s);                 /* Get key's end field no.  */
  137.                 for ( ; isdigit(*s); s++) ;
  138.                 if (*s == '.') {
  139.                     keyp->echar = atoi(++s);    /* Get char offset for field*/
  140.                     for ( ; isdigit(*s); s++) ;
  141.                 } else {
  142.                     keyp->echar = 0;            /* 0 is default             */
  143.                 }
  144.                 for ( ; *s != '\0'; s++) {      /* 'bdfinr' flags for key   */
  145.                     if (qualif = bdfinr(*s)) {
  146.                         keyflags |= qualif;  /* add flag                 */
  147.                     } else {
  148.                         s[1] = '\0';
  149.                         error("invalid option %s\n",s);
  150.                     }
  151.                 }
  152.             } else {
  153.                 efld = keyp->echar = 0;
  154.             }
  155.             if (keyflags == 0) {                /* If no field flags        */
  156.                keyflags = options;              /* Take global ones         */
  157.             }
  158.             keyp->flds = efld - keyp->bfld;
  159.             keyp->bis0 = keyp->bfld == 0 && keyp->bchar == 0;
  160.             keyp->eis0 = efld == 0 && keyp->echar == 0;
  161.             keyp->cmp = getcmp(keyflags,keyp->eis0);
  162.         }
  163.     }
  164.  
  165.     bestio(2048);                               /* Possibly initiate bestio */
  166.  
  167.     if (nkeys == 0) {                           /* No key specified         */
  168.         nkeys++;
  169.         firstkey.next = (key *)0;
  170.         firstkey.cmp = getcmp(options,1);
  171.         firstkey.bfld = 0;
  172.         firstkey.bchar = 0;
  173.         firstkey.echar = 0;
  174.         firstkey.flds = 0;
  175.         firstkey.bis0 = 1;
  176.         firstkey.eis0 = 1;
  177.     }
  178.  
  179.     fieldfunc = (options & SEPARATOR) ? getsepfld : getspafld;
  180.  
  181.     if (nkeys == 1) {                           /* One key only             */
  182.         if (firstkey.bis0) {
  183.             if (firstkey.eis0) {
  184.